// Copyright (C) 1953-2023 NUDT
// Verilog module name - packet_tag_discard 
// Version: V4.1.0.0.20230103
// Created:
//         by - fenglin 
////////////////////////////////////////////////////////////////////////////
// Description:
//         discard c-tag and r-tag.
///////////////////////////////////////////////////////////////////////////

`timescale 1ns/1ps

module packet_tag_discard
(
        i_clk  ,
        i_rst_n,                
        
        iv_data         ,
        i_data_wr       ,
        o_data_ready    ,
        
        ov_data         ,
        o_data_wr       ,
        iv_fifo_usedw        
);

// I/O
// clk & rst
input                  i_clk;   
input                  i_rst_n;
//tsntag & bufid input from host_port
(*MARK_DEBUG="true"*)input       [8:0]      iv_data             ;
(*MARK_DEBUG="true"*)input                  i_data_wr           ;
                     output                 o_data_ready        ;
// transmit pkt to phy     
(*MARK_DEBUG="true"*)output  reg [8:0]      ov_data             ;
(*MARK_DEBUG="true"*)output  reg            o_data_wr           ;
                     input       [4:0]      iv_fifo_usedw       ;

assign               o_data_ready = (iv_fifo_usedw <= 5'd12) ? 1'b1:1'b0;
//***************************************************
//                delay 1 cycles
//***************************************************
reg         [8:0]      rv_data  ;
reg                    r_data_wr;
always@(posedge i_clk or negedge i_rst_n)begin
    if(!i_rst_n) begin
        rv_data                   <= 9'b0;
        r_data_wr                 <= 1'b0;
    end
    else begin
        rv_data                   <= iv_data  ;
        r_data_wr                 <= i_data_wr;
    end
end

//***************************************************
//                   fifo write
//***************************************************
reg         [2:0]       rv_ptd_state;
// internal reg&wire
localparam  IDLE_S             = 3'd0,
            OUTPUT_MAC_S       = 3'd1,
            JUDGE_ETHTYPE_S    = 3'd2,
            DISCARD_CTAG_S     = 3'd3,
            JUDGE_RTAG_S       = 3'd4,
            DISCARD_RTAG_S     = 3'd5,
            TRANSMIT_DATA_S    = 3'd6;

reg         [4:0]      rv_byte_cnt    ;
//reg                    r_ctag_flag    ;
//reg                    r_rtag_flag    ;
always@(posedge i_clk or negedge i_rst_n)begin
    if(!i_rst_n) begin
        ov_data                   <= 9'b0  ;
        o_data_wr                 <= 1'b0  ;
                                           
        rv_byte_cnt               <= 5'b0  ;
        //r_ctag_flag               <= 1'b0  ;
        //r_rtag_flag               <= 1'b0  ;

        rv_ptd_state              <= IDLE_S;
    end
    else begin
        case(rv_ptd_state)
            IDLE_S:begin
                if(r_data_wr && rv_data[8])begin
                    ov_data               <= rv_data     ;
                    o_data_wr             <= r_data_wr   ; 
                                                         
                    rv_byte_cnt           <= 1'b1        ; 
                    rv_ptd_state          <= OUTPUT_MAC_S;  
                end
                else begin
                    ov_data               <= 9'b0  ;
                    o_data_wr             <= 1'b0  ;

                    rv_byte_cnt           <= 1'b0  ;
                    rv_ptd_state          <= IDLE_S; 
                end
            end
            OUTPUT_MAC_S:begin
                ov_data               <= rv_data           ;              

                if(r_data_wr)begin
                    rv_byte_cnt           <= rv_byte_cnt + 1'b1;
                    //r_ctag_flag           <= 1'b0            ;
                    //r_rtag_flag           <= 1'b0            ;   
                end
                else begin
                    rv_byte_cnt           <= rv_byte_cnt       ;
                end

                if(o_data_ready)begin
                    if(rv_byte_cnt < 5'd12)begin
                        o_data_wr             <= r_data_wr         ;  
                        rv_ptd_state          <= OUTPUT_MAC_S      ;    
                    end
                    else begin
                        if({rv_data[7:0],iv_data[7:0]} == 16'h8100)begin//c-tag.
                            o_data_wr             <= 1'b0          ;
                            rv_ptd_state          <= DISCARD_CTAG_S;
                        end
                        else begin
                            o_data_wr             <= r_data_wr         ;
                            rv_ptd_state          <= TRANSMIT_DATA_S   ;
                        end
                    end
                end
                else begin
                    o_data_wr             <= r_data_wr         ;
                    rv_ptd_state          <= OUTPUT_MAC_S      ;    
                end
            end
            /*
            JUDGE_ETHTYPE_S:begin
                rv_byte_cnt               <= 5'b0          ;
                if(i_ctag_rtag_flag == 1'b1)begin//c-tag
                    ov_data               <= 9'b0          ;
                    o_data_wr             <= 1'b0          ;
                    
                    rv_ptd_state          <= DISCARD_CTAG_S;
                end
                else begin
                    ov_data               <= iv_data         ;
                    o_data_wr             <= i_data_wr       ;

                    rv_byte_cnt           <= 5'b0            ;
                    rv_ptd_state          <= TRANSMIT_DATA_S ;
                end
            end
            */
            DISCARD_CTAG_S:begin  
                ov_data                   <= rv_data               ;             
                
                if(r_data_wr)begin
                    rv_byte_cnt           <= rv_byte_cnt + 1'b1 ; 
                end
                else begin
                    rv_byte_cnt           <= rv_byte_cnt        ; 
                end

                if(rv_byte_cnt < 5'd16)begin
                    o_data_wr             <= 1'b0               ;  
                    rv_ptd_state          <= DISCARD_CTAG_S     ;
                end
                else begin
                    if({rv_data[7:0],iv_data[7:0]} == 16'hf1c1)begin//r-tag.
                        o_data_wr         <= 1'b0               ;
                        rv_ptd_state      <= DISCARD_RTAG_S     ;
                    end
                    else begin
                        o_data_wr         <= r_data_wr          ;
                        rv_ptd_state      <= TRANSMIT_DATA_S    ;
                    end
                end
            end
            /*
            JUDGE_RTAG_S:begin
                rv_byte_cnt               <= 5'b0           ;
                if(i_ctag_rtag_flag == 1'b1)begin//r-tag
                    ov_data               <= 9'b0           ;
                    o_data_wr             <= 1'b0           ; 
                    
                    //r_rtag_flag           <= 1'b1           ;
                    rv_ptd_state          <= DISCARD_RTAG_S ;                    
                end
                else begin
                    ov_data               <= iv_data        ;
                    o_data_wr             <= i_data_wr      ;
                    
                    //r_rtag_flag           <= 1'b0           ;
                    rv_ptd_state          <= TRANSMIT_DATA_S;                    
                end
            end
            */
            DISCARD_RTAG_S:begin
                ov_data                   <= 9'b0               ;
                o_data_wr                 <= 1'b0               ;                
                
                if(r_data_wr)begin
                    rv_byte_cnt           <= rv_byte_cnt + 1'b1 ; 
                end
                else begin
                    rv_byte_cnt           <= rv_byte_cnt        ; 
                end

                if(rv_byte_cnt < 5'd21)begin
                    rv_ptd_state          <= DISCARD_RTAG_S     ;
                end
                else begin
                    rv_ptd_state          <= TRANSMIT_DATA_S    ;
                end
            end
            TRANSMIT_DATA_S:begin
                ov_data               <= rv_data           ;
                o_data_wr             <= r_data_wr         ;
 
                if(r_data_wr && rv_data[8])begin
                    rv_ptd_state          <= IDLE_S   ; 
                end
                else begin
                    rv_ptd_state          <= TRANSMIT_DATA_S   ; 
                end   
            end
            default:begin
                ov_data                   <= 9'b0  ;
                o_data_wr                 <= 1'b0  ;
                                                   
                rv_byte_cnt               <= 5'b0  ;

                rv_ptd_state              <= IDLE_S;
            end
        endcase     
    end
end

endmodule